/**
 * PaperService.java
 * Version 1.0.0
 * Created on 2018年7月14日
 */
package com.yincheng.oes.business.exam.createpaper.service;

import com.yincheng.oes.business.base.entity.QuestionKnowledgeOutlineExt;
import com.yincheng.oes.business.base.mapper.QuestionKnowledgeOutlineMapper;
import com.yincheng.oes.business.consist.PaperStatusEnum;
import com.yincheng.oes.business.exam.base.entity.Paper;
import com.yincheng.oes.business.exam.base.entity.PaperDetailUnDo;
import com.yincheng.oes.business.exam.base.entity.PaperQuesDetail;
import com.yincheng.oes.business.exam.base.entity.PaperUndo;
import com.yincheng.oes.business.exam.base.mapper.PaperDetailMapper;
import com.yincheng.oes.business.exam.base.mapper.PaperMapper;
import com.yincheng.oes.business.exam.export.model.ExportPaperParam;
import com.yincheng.oes.business.util.ExportWord;
import com.yincheng.oes.sso.util.UserUtils;
import freemarker.template.TemplateException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.*;

import static com.yincheng.oes.business.util.PaperUtils.getAnswersList;

/**
 * @author yangsy
 * @version 1.0.0
 * @since 创建时间：2018年7月14日
 * 功能描述：试卷服务类
 * 邮箱地址：446948434@qq.com
 */
@Service
public class PaperService {

    @Autowired
    private PaperMapper paperMapper;

    @Autowired
    private PaperDetailMapper paperDetailMapper;

    @Autowired
    private QuestionKnowledgeOutlineMapper questionKnowledgeOutlineMapper;

    /**
     * 保存或新增试卷及题目列表数据
     *
     * @param paper
     */
    @Transactional
    public void savePaper(Paper paper) {
        List<PaperQuesDetail> paperDetails = new ArrayList<PaperQuesDetail>();
        List<PaperQuesDetail> oldPaperDetails = paper.getPaperDetails();

        Float totalScore = (float) 0;
        for (PaperQuesDetail paperQuesDetail : oldPaperDetails) {
            if (paperQuesDetail.getQuesId() != null) {
                totalScore = totalScore + paperQuesDetail.getScore();
                paperDetails.add(paperQuesDetail);
            }
        }
        paper.setTotalScore(totalScore);

        int i = paperMapper.update(paper);
        if (i == 0) {
            // 新增试卷和题目列表
            paper.setCreateTime(new Date());
            paper.setCreateUserAccount(UserUtils.getUser().getUserAccount());
            paper.setCreateUserName(UserUtils.getUser().getUserName());
            String status = StringUtils.isEmpty(paper.getStatus()) ? "1" : paper.getStatus();
            paper.setStatus(status);
            paperMapper.insert(paper);
        }
        // 先删除再插入题目明细
        paperDetailMapper.deleteByPaperId(paper.getId());
        paperDetails.forEach(e -> {
            e.setCreateTime(new Date());
            e.setOrderNum(paperDetails.indexOf(e));
            paperDetailMapper.insert(e);
        });

    }

    /**
     * 根据试卷id获取试卷信息和试卷的题目列表信息
     *
     * @param paperId
     * @return
     */
    public Paper getPaper(String paperId) {
        Paper paper = paperMapper.selectById(paperId);
        if (paper == null) {
            paper = gerNewPaper(paperId);
            return paper;
        }
        List<PaperQuesDetail> paperDetails = paperDetailMapper.selectByPaperId(paperId);
        List<QuestionKnowledgeOutlineExt> quesOutlines = questionKnowledgeOutlineMapper.selectByPaperId(paperId);
        for (PaperQuesDetail paperDetail : paperDetails) {
            Integer quesId = paperDetail.getQuesId();
            List<String> contents = new ArrayList<String>();
            for (QuestionKnowledgeOutlineExt knowledgeOutline : quesOutlines) {
                if (knowledgeOutline.getQuesId().equals(quesId)) {
                    String outlineContext = knowledgeOutline.getContents();
                    contents.add(outlineContext);
                } else
                    continue;
            }
            paperDetail.setOutlineTexts(contents);
        }
        paper.setPaperDetails(paperDetails);
        return paper;
    }

    /**
     * 获取新的试卷实体
     *
     * @return
     */
    public Paper gerNewPaper(String paperId) {
        Paper paper = new Paper();
        paper.setId(paperId);
        paper.setCreateTime(new Date());
        paper.setStatus("1");// 起草中
        paper.setCreateUserAccount(UserUtils.getUser().getUserAccount());
        paper.setCreateUserName(UserUtils.getUser().getUserName());
        return paper;
    }

    /**
     * 导出试卷
     *
     * @param param
     * @param os
     * @throws IOException
     * @throws TemplateException
     */
    public void exportUndoPaper(ExportPaperParam param, OutputStream os) throws IOException, TemplateException {
        PaperUndo undoPaper = getExportUndoPaper(param.getPaperId());
        Map<String, Object> dataMap = getTemplateDataMap(undoPaper);
        dataMap.put("paperHeader", param.getPaperHeader());
        dataMap.put("paperTitle", param.getPaperTitle());
        String fileName = "集训营试卷模版.ftl";
        ExportWord.exportWord(dataMap, fileName, os);
    }

    private Map<String, Object> getTemplateDataMap(PaperUndo undoPaper) {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("paperName", undoPaper.getPaperName());
        List<PaperDetailUnDo> details = undoPaper.getDetails();
        dataMap.put("details", details);
        List<String> answers = getAnswersList();
        dataMap.put("answers", answers);
        return dataMap;
    }

    public void exportPaperWithAnswer(String paperId, OutputStream os) throws IOException, TemplateException {
        PaperUndo undoPaper = getExportUndoPaper(paperId);
        Map<String, Object> dataMap = getTemplateDataMap(undoPaper);
        String fileName = "导出试卷带解析模板.ftl";
        ExportWord.exportWord(dataMap, fileName, os);
    }

    public PaperUndo getExportUndoPaper(String paperId) {
        DecimalFormat df = new DecimalFormat("000");
        PaperUndo paperUndo = new PaperUndo();
        List<PaperDetailUnDo> details = new ArrayList<PaperDetailUnDo>();
        Map<String, PaperDetailUnDo> mapList = new HashMap<String, PaperDetailUnDo>();
        Paper paper = getPaper(paperId);
        paperUndo.setPaperName(paper.getPaperName());
        List<PaperQuesDetail> paperDetails = paper.getPaperDetails();
        for (PaperQuesDetail paperQuesDetail : paperDetails) {
            PaperDetailUnDo detailUnDo = new PaperDetailUnDo();
            String quesType = paperQuesDetail.getQuesType();
            Integer orderNum = paperQuesDetail.getOrderNum();
            String quesNum = df.format(orderNum + 1);
            paperQuesDetail.setQuesNum(quesNum);
            detailUnDo.setQuesType(quesType);
            detailUnDo.setRealQuestionYear(paperQuesDetail.getRealQuestionYear());
            detailUnDo.setRealQuestionNo(paperQuesDetail.getRealQuestionNo());
            if ("1".equals(quesType) || "4".equals(quesType)) {
                List<PaperQuesDetail> undoDetails = new ArrayList<PaperQuesDetail>();
                undoDetails.add(paperQuesDetail);
                detailUnDo.setQuesDetails(undoDetails);
                detailUnDo.setQuesNum(orderNum);
                details.add(detailUnDo);
            }
            if ("2".equals(quesType)) {
                String relationCode = paperQuesDetail.getRelationCode();
                PaperDetailUnDo unDoDetail = mapList.get(relationCode);
                if (unDoDetail == null) {
                    unDoDetail = detailUnDo;
                    List<PaperQuesDetail> undoDetails = new ArrayList<PaperQuesDetail>();
                    undoDetails.add(paperQuesDetail);
                    unDoDetail.setQuesDetails(undoDetails);
                    unDoDetail.setQuesNum(orderNum);
                    unDoDetail.setSharedCount(1);
                    unDoDetail.setSharedStem(paperQuesDetail.getQuestion());
                    mapList.put(relationCode, unDoDetail);
                } else {
                    List<PaperQuesDetail> undoDetails = unDoDetail.getQuesDetails();
                    undoDetails.add(paperQuesDetail);
                    unDoDetail.setQuesDetails(undoDetails);
                    unDoDetail.setSharedCount(unDoDetail.getSharedCount() + 1);
                    mapList.put(relationCode, unDoDetail);
                }

            }
            if ("3".equals(quesType)) {
                String relationCode = paperQuesDetail.getRelationCode();
                PaperDetailUnDo unDoDetail = mapList.get(relationCode);
                if (unDoDetail == null) {
                    unDoDetail = detailUnDo;
                    List<PaperQuesDetail> undoDetails = new ArrayList<PaperQuesDetail>();
                    undoDetails.add(paperQuesDetail);
                    unDoDetail.setQuesDetails(undoDetails);
                    unDoDetail.setQuesNum(orderNum);
                    unDoDetail.setSharedCount(1);
                    mapList.put(relationCode, unDoDetail);
                } else {
                    List<PaperQuesDetail> undoDetails = unDoDetail.getQuesDetails();
                    undoDetails.add(paperQuesDetail);
                    unDoDetail.setQuesDetails(undoDetails);
                    unDoDetail.setSharedCount(unDoDetail.getSharedCount() + 1);
                    mapList.put(relationCode, unDoDetail);
                }
            }
        }
        Set<String> relationCodes = mapList.keySet();
        for (String relationCode : relationCodes) {
            PaperDetailUnDo detailUnDo = mapList.get(relationCode);
            details.add(detailUnDo);
        }
        details.sort(Comparator.comparingInt(PaperDetailUnDo::getQuesNum));// 升序
        paperUndo.setDetails(details);
        return paperUndo;
    }

    public void changeStatus(String paperId) {
        Paper paper = paperMapper.selectById(paperId);
        if (PaperStatusEnum.PUBLISH.getStatus().equals(paper.getStatus())) {
            paper.setStatus(PaperStatusEnum.INVALID.getStatus());
            paperMapper.update(paper);
            return;
        }
        if (PaperStatusEnum.INVALID.getStatus().equals(paper.getStatus())) {
            paper.setStatus(PaperStatusEnum.PUBLISH.getStatus());
            paperMapper.update(paper);
        }
    }

    public void copyPaper(String paperId) {
        Paper paper = getPaper(paperId);
        resetPaper(paper);
        savePaper(paper);
    }

    private void resetPaper(Paper paper) {
        paper.setStatus(PaperStatusEnum.DRAFT.getStatus());
        paper.setPaperName(paper.getPaperName() + "_拷贝");
        String id = UUID.randomUUID().toString();
        paper.setId(id);
        paper.setCreateTime(new Date());
        List<PaperQuesDetail> paperDetails = paper.getPaperDetails();
        if (CollectionUtils.isEmpty(paperDetails)) {
            return;
        }
        for (PaperQuesDetail paperDetail : paperDetails) {
            paperDetail.setPaperId(id);
            paperDetail.setId(null);
        }
        paper.setPaperDetails(paperDetails);
    }
}
